package com.ylr.base.common.exception.handler;

import com.ylr.base.common.enums.ResultEnum;
import com.ylr.base.common.tool.Result;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2023-04-30 22:10:36
 * className: SentinelExceptionHandler sentinel异常处理器类
 * version: 1.0
 * description:
 */
public class SentinelExceptionHandler implements BlockExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(SentinelExceptionHandler.class);

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) {

        String requestURI = request.getRequestURI();

        if (e instanceof FlowException) {
            log.warn("{} - 请求限流", requestURI, e);
        } else if (e instanceof DegradeException) {
            log.warn("{} - 请求降级", requestURI, e);
        } else if (e instanceof ParamFlowException) {
            log.warn("{} - 热点参数限流", requestURI, e);
        } else if (e instanceof SystemBlockException) {
            log.warn("{} - 规则配置限流", requestURI, e);
        } else if (e instanceof AuthorityException) {
            log.warn("{} - 规则配置限流", requestURI, e);
        } else {
            log.warn("{} - 位置异常限流。message={}", requestURI, e.getMessage(), e);
        }
        // 结果输出
        writeResponse(request, response);
    }

    private void writeResponse(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 重置response
            response.reset();
            response.setStatus(ResultEnum.SUCCESS.getCode());
            // 设置结果类型
            response.setContentType("application/json;charset=utf-8");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
            // 设置编码类型
            response.setCharacterEncoding("utf-8");
            Result<Object> result = Result.getResult(ResultEnum.LIMIT_FAIL);
            response.getWriter().println(JSON.toJSONString(result));
        } catch (IOException e) {
            log.error("设置请求输出结果异常。message={}", e.getMessage(), e);
        }
    }
}
